package cn.com.libertymutual.sp.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.com.libertymutual.core.redis.util.RedisUtils;
import cn.com.libertymutual.core.util.Constants;
import cn.com.libertymutual.core.util.Current;
import cn.com.libertymutual.core.web.ServiceResult;
import cn.com.libertymutual.sp.bean.SysOperationLog;
import cn.com.libertymutual.sp.bean.TbSpServiceconfig;
import cn.com.libertymutual.sp.dao.OperationLogDao;
import cn.com.libertymutual.sp.dao.ServiceMenuDao;
import cn.com.libertymutual.sp.service.api.ServiceMenuService;
import cn.com.libertymutual.sys.bean.SysServiceInfo;
import cn.com.libertymutual.sys.dao.ISysServiceInfoDao;
import cn.com.libertymutual.sys.service.api.IInitSharedMemory;

@Service("serviceMenuService")
public class ServiceMenuServiceImpl implements ServiceMenuService {

	private Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	private ServiceMenuDao serviceMenuDao;
	@Autowired
	private OperationLogDao operationLogDao;
	@Resource
	private RedisUtils redisUtils;
	@Resource
	private ISysServiceInfoDao iSysServiceInfoDao;
	@Autowired
	private IInitSharedMemory initSharedMemory;

	@Override
	public ServiceResult menuList(String sorttype) {

		ServiceResult sr = new ServiceResult();
		List<TbSpServiceconfig> dblist = (List<TbSpServiceconfig>) redisUtils.get(Constants.SERVICE_MENU_INFO + sorttype);
		if (null != dblist && dblist.size() != 0) {
			sr.setResult(dblist);
		} else {
			Sort sort = null;
			if ("ASC".equals(sorttype)) {
				sort = new Sort(Direction.ASC, "serialNo");
			} else {
				sort = new Sort(Direction.DESC, "serialNo");
			}

			List<TbSpServiceconfig> list = serviceMenuDao.findAll(new Specification<TbSpServiceconfig>() {
				@Override
				public Predicate toPredicate(Root<TbSpServiceconfig> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

					List<Predicate> predicate = new ArrayList<Predicate>();

					predicate.add(cb.equal(root.get("isValidate").as(String.class), "1"));

					Predicate[] pre = new Predicate[predicate.size()];
					return query.where(predicate.toArray(pre)).getRestriction();
				}
			}, sort);
			sr.setResult(list);
			redisUtils.set(Constants.SERVICE_MENU_INFO + sorttype, list);
		}
		return sr;
	}

	@Transactional(propagation = Propagation.REQUIRED) // 事务
	@Override
	public ServiceResult addService(TbSpServiceconfig tbSpServiceconfig) {
		ServiceResult sr = new ServiceResult();
		TbSpServiceconfig smenu = serviceMenuDao.save(tbSpServiceconfig);
		sr.setResult(smenu);
		SysOperationLog operLog = new SysOperationLog();
		operLog.setIP(Current.IP.get());
		operLog.setLevel("1");
		operLog.setModule("服务菜单配置");
		operLog.setOperationTime(new Date());
		operLog.setUserId(Current.userInfo.get().getUserId());
		operLog.setContent("添加服务菜单-ID:" + smenu.getId());
		operationLogDao.save(operLog);
		redisUtils.deletelike(Constants.SERVICE_MENU_INFO);
		return sr;
	}

	@Transactional(propagation = Propagation.REQUIRED) // 事务
	@Override
	public ServiceResult updateService(TbSpServiceconfig tbSpServiceconfig) {
		ServiceResult sr = new ServiceResult();
		TbSpServiceconfig smenu = serviceMenuDao.save(tbSpServiceconfig);
		sr.setResult(smenu);

		SysOperationLog operLog = new SysOperationLog();
		operLog.setIP(Current.IP.get());
		operLog.setLevel("2");
		operLog.setModule("服务菜单配置");
		operLog.setOperationTime(new Date());
		operLog.setUserId(Current.userInfo.get().getUserId());
		operLog.setContent("修改服务菜单-ID" + smenu.getId());
		operationLogDao.save(operLog);
		redisUtils.deletelike(Constants.SERVICE_MENU_INFO);
		return sr;
	}

	@Transactional(propagation = Propagation.REQUIRED) // 事务
	@Override
	public ServiceResult removeService(String[] list) {
		ServiceResult sr = new ServiceResult();
		TbSpServiceconfig smenu = null;
		SysOperationLog operLog = null;
		for (int i = 0; i < list.length; i++) {
			smenu = serviceMenuDao.findById(Integer.parseInt(list[i])).get();
			if (null != smenu) {
				operLog = new SysOperationLog();
				operLog.setIP(Current.IP.get());
				operLog.setLevel("3");
				operLog.setModule("服务菜单配置");
				operLog.setOperationTime(new Date());
				operLog.setUserId(Current.userInfo.get().getUserId());
				operLog.setContent("删除了" + smenu.getServiceCname() + "服务菜单");
				operationLogDao.save(operLog);
				serviceMenuDao.deleteById(Integer.parseInt(list[i]));
			}
		}
		redisUtils.deletelike(Constants.SERVICE_MENU_INFO);
		sr.setSuccess();
		return sr;
	}

	@Override
	public ServiceResult menuListWeb(String isValidate, String serviceCname, String serviceType, String toType, int pageNumber, int pageSize) {
		ServiceResult sr = new ServiceResult();
		Sort sort = new Sort(Direction.DESC, "serialNo");

		sr.setResult(serviceMenuDao.findAll(new Specification<TbSpServiceconfig>() {
			@Override
			public Predicate toPredicate(Root<TbSpServiceconfig> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicate = new ArrayList<Predicate>();
				if (StringUtils.isNotEmpty(isValidate) && !"-1".equals(isValidate)) {
					log.info(isValidate);
					predicate.add(cb.equal(root.get("isValidate").as(String.class), isValidate));
				}
				if (StringUtils.isNotEmpty(serviceCname)) {
					log.info(serviceCname);
					predicate.add(cb.like(root.get("serviceCname").as(String.class), "%" + serviceCname + "%"));
				}
				if (StringUtils.isNotEmpty(serviceType) && !"-1".equals(serviceType)) {
					log.info(serviceType);
					predicate.add(cb.equal(root.get("serviceType").as(String.class), serviceType));
				}
				if (StringUtils.isNotEmpty(toType) && !"-1".equals(toType)) {
					log.info(toType);
					predicate.add(cb.equal(root.get("toType").as(String.class), toType));
				}
				Predicate[] pre = new Predicate[predicate.size()];
				return query.where(predicate.toArray(pre)).getRestriction();
			}
		}, PageRequest.of(pageNumber - 1, pageSize, sort)));
		return sr;
	}

	@Override
	public ServiceResult thirdServiceInfo(String url, String userName, Integer pageNumber, Integer pageSize) {
		ServiceResult sr = new ServiceResult();
		Sort sort = new Sort(Direction.DESC, "id");
		sr.setResult(iSysServiceInfoDao.findAll(new Specification<SysServiceInfo>() {
			@Override
			public Predicate toPredicate(Root<SysServiceInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicate = new ArrayList<Predicate>();
				if (StringUtils.isNotEmpty(url)) {
					log.info(url);
					predicate.add(cb.like(root.get("url").as(String.class), "%" + url + "%"));
				}
				if (StringUtils.isNotEmpty(userName)) {
					log.info(userName);
					predicate.add(cb.like(root.get("userName").as(String.class), "%" + userName + "%"));
				}
				Predicate[] pre = new Predicate[predicate.size()];
				return query.where(predicate.toArray(pre)).getRestriction();
			}
		}, PageRequest.of(pageNumber - 1, pageSize, sort)));
		return sr;
	}

	@Override
	public ServiceResult updateServiceInfo(Integer id, String modifyDate, String url) {
		ServiceResult sr = new ServiceResult();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			Date time = sdf.parse(modifyDate);
			iSysServiceInfoDao.updateServiceInfo(id, time, url);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 刷新缓存
		initSharedMemory.initServiceInfo();
		sr.setSuccess();
		return sr;
	}

}
